Objetivo 3

Objetivo 3#

import pandas as pd
import numpy as np
import plotly.express as px
import altair as alt
import datos
import plotly.graph_objects as go
import warnings

warnings.simplefilter(action='ignore', category=FutureWarning)
agrupaciones = ['sexo','tipo_de_afiliacion','edad_grupo'] + ['hipertension','infarto de miocardio','arritmia','insuficiencia cardiaca congestiva','nefropatia']+['fumador','bebedor']
variable = 'Hipolipemiante'
edad_intervals = [0, 49, 59, 79, 150]
edad_labels = ['<50', '50-59', '60-79', '>80']

# Creación de grupo por intervalos de edad
datos.datos['edad_grupo'] = pd.cut(
    datos.datos['edad_calculada'], bins=edad_intervals, labels=edad_labels, right=False
)

for agrupacion in agrupaciones:
    # Crear tabla de frecuencias cruzadas con totales incluidos
    tabla_frecuencias = pd.crosstab(
        datos.datos[agrupacion], datos.datos[variable], margins=True, margins_name="Total"
    )
    
    # Reordenar las columnas en el orden 'si', 'no', 'Total'
    if 'si' in tabla_frecuencias.columns and 'no' in tabla_frecuencias.columns:
        tabla_frecuencias = tabla_frecuencias[['si', 'no', 'Total']]
    
    # Calcular porcentajes por filas (excluyendo la fila 'Total')
    totales_fila = tabla_frecuencias.loc[:, "Total"]
    porcentajes = (tabla_frecuencias.div(totales_fila, axis=0) * 100).round(2)
    
    # Combinar frecuencias y porcentajes en un formato "valor (porcentaje%)"
    tabla_final_percent = tabla_frecuencias.astype(str) + " (" + porcentajes.astype(str) + "%)"
    
   
    # Ajustar para excluir la fila "Total" al mostrar porcentajes
    if "Total" in tabla_frecuencias.index:
        tabla_final_percent.iloc[-1, :] = tabla_frecuencias.loc["Total", :].astype(str)  # Fila "Total" no tiene porcentaje

    print(tabla_final_percent)
    titulo_esquina = f"{agrupacion}/{variable}"
    
    # Crear tabla visual con Plotly
    fig = go.Figure(data=[go.Table(
        header=dict(
            values=[titulo_esquina] + list(tabla_final_percent.columns),
            fill_color='paleturquoise',
            align='center'
        ),
        cells=dict(
            values=[list(tabla_final_percent.index)] + [tabla_final_percent[col].values for col in tabla_final_percent.columns],
            fill_color='lavender',
            align='center'
        )
    )])
    
    # Ajustar diseño de la tabla
    fig.update_layout(
        title=f"Tabla de Frecuencias (por Fila): {agrupacion} vs {variable}"
    )
    fig.show()
Hipolipemiante            si            no         Total
sexo                                                    
femenino        206 (62.24%)  125 (37.76%)  331 (100.0%)
masculino       377 (60.61%)  245 (39.39%)  622 (100.0%)
Total                    583           370           953
Hipolipemiante                si            no         Total
tipo_de_afiliacion                                          
contributivo        243 (56.78%)  185 (43.22%)  428 (100.0%)
otro                  1 (100.0%)      0 (0.0%)    1 (100.0%)
polizas de seguro     1 (100.0%)      0 (0.0%)    1 (100.0%)
prepagada               0 (0.0%)    1 (100.0%)    1 (100.0%)
regimen especial     30 (52.63%)   27 (47.37%)   57 (100.0%)
subsidiado          308 (66.24%)  157 (33.76%)  465 (100.0%)
Total                        583           370           953
Hipolipemiante            si            no         Total
edad_grupo                                              
<50              30 (65.22%)   16 (34.78%)   46 (100.0%)
50-59            90 (62.07%)   55 (37.93%)  145 (100.0%)
60-79           380 (59.38%)  260 (40.62%)  640 (100.0%)
>80              83 (68.03%)   39 (31.97%)  122 (100.0%)
Total                    583           370           953
Hipolipemiante            si            no         Total
hipertension                                            
no              156 (60.94%)  100 (39.06%)  256 (100.0%)
si              427 (61.26%)  270 (38.74%)  697 (100.0%)
Total                    583           370           953
Hipolipemiante                  si            no         Total
infarto de miocardio                                          
no                    364 (62.12%)  222 (37.88%)  586 (100.0%)
si                    219 (59.67%)  148 (40.33%)  367 (100.0%)
Total                          583           370           953
Hipolipemiante           si           no         Total
arritmia                                              
no              567 (61.1%)  361 (38.9%)  928 (100.0%)
si               16 (64.0%)    9 (36.0%)   25 (100.0%)
Total                   583          370           953
Hipolipemiante                               si            no         Total
insuficiencia cardiaca congestiva                                          
no                                 527 (61.28%)  333 (38.72%)  860 (100.0%)
si                                  56 (60.22%)   37 (39.78%)   93 (100.0%)
Total                                       583           370           953
Hipolipemiante            si            no         Total
nefropatia                                              
no              583 (61.37%)  367 (38.63%)  950 (100.0%)
si                  0 (0.0%)    3 (100.0%)    3 (100.0%)
Total                    583           370           953
Hipolipemiante            si            no         Total
fumador                                                 
no              390 (64.14%)  218 (35.86%)  608 (100.0%)
si              193 (55.94%)  152 (44.06%)  345 (100.0%)
Total                    583           370           953
Hipolipemiante            si            no         Total
bebedor                                                 
no              478 (62.32%)  289 (37.68%)  767 (100.0%)
si              105 (56.45%)   81 (43.55%)  186 (100.0%)
Total                    583           370           953
import pandas as pd
import plotly.graph_objects as go

# Definición de intervalos
hb1a_interv = {'POC_hba1c(%)': [0, 5.7, 6.4, 7.5, 10, max(datos.datos['POC_hba1c(%)']) + 4]}
pres_sist = {'masculino': [0, 120, 130, 139, max(datos.datos['presion_arterial_sistolica'])],
             'femenino': [0, 120, 130, 139, max(datos.datos['presion_arterial_sistolica'])]}
IMC_interv = {'IMC': [0, 19.9, 24.9, 29.9, 40, max(datos.datos['IMC']) + 1]}
per_inter = {'masculino': [0, 94, 102, max(datos.datos['perimetro_abdominal'])],
             'femenino': [0, 80, 88, max(datos.datos['perimetro_abdominal'])]}
pres_diast = {'masculino': [0, 80, 90, 120, max(datos.datos['presion_arterial_diastolica'])],
              'femenino': [0, 80, 90, 120, max(datos.datos['presion_arterial_diastolica'])]}

# Creación de intervalos en el DataFrame
datos.datos['POC_hba1c_intervalo'] = pd.cut(datos.datos['POC_hba1c(%)'], bins=hb1a_interv['POC_hba1c(%)']).astype(str)
datos.datos['IMC_intervalo'] = pd.cut(datos.datos['IMC'], bins=IMC_interv['IMC']).astype(str)
datos.datos['perimetro_abdominal_intervalo'] = pd.cut(datos.datos['perimetro_abdominal'], bins=per_inter['masculino']).astype(str)
datos.datos['presion_arterial_sistolica_intervalo'] = pd.cut(datos.datos['presion_arterial_sistolica'], bins=pres_sist['masculino']).astype(str)
datos.datos['presion_arterial_diastolica_intervalo'] = pd.cut(datos.datos['presion_arterial_diastolica'], bins=pres_diast['masculino']).astype(str)

agrupaciones = ['sexo', 'edad_grupo', 'tipo_de_afiliacion']
variables = ['IMC_intervalo', 'POC_hba1c_intervalo', 'perimetro_abdominal_intervalo', 
             'presion_arterial_sistolica_intervalo', 'presion_arterial_diastolica_intervalo']

for variable in variables:
    for agrupacion in agrupaciones:
        # Crear tabla de frecuencias cruzadas
        tabla_frecuencias = pd.crosstab(datos.datos[agrupacion], datos.datos[variable])

        # Agregar columna de totales para las filas
        tabla_frecuencias['Total'] = tabla_frecuencias.sum(axis=1)

        # Calcular porcentajes por fila
        porcentajes = tabla_frecuencias.div(tabla_frecuencias['Total'], axis=0) * 100

        # Agregar fila de totales
        tabla_frecuencias.loc['Total'] = tabla_frecuencias.sum(axis=0)
        porcentajes.loc['Total'] = [100.0] * len(tabla_frecuencias.columns)

        # Combinar frecuencias y porcentajes
        tabla_final_percent = tabla_frecuencias.astype(str) + " (" + porcentajes.round(2).astype(str) + "%)"
        
        # Eliminar columnas con valores `nan` si existen
        if 'nan' in tabla_final_percent.columns:
            tabla_final_percent = tabla_final_percent.drop(['nan'], axis=1)
        
        # Crear tabla visual con Plotly
        fig = go.Figure(data=[go.Table(
            header=dict(
                values=['Categoría'] + list(tabla_final_percent.columns),
                fill_color='paleturquoise',
                align='center'
            ),
            cells=dict(
                values=[tabla_final_percent.index] + [tabla_final_percent[col].values for col in tabla_final_percent.columns],
                fill_color='lavender',
                align='center'
            )
        )])

        # Título dinámico de la tabla
        fig.update_layout(
            title=f'Tabla de Frecuencias: {agrupacion} vs {variable}'
        )
        fig.show()
import plotly.io as pio

pio.renderers.default = 'notebook'

medicamentos = {
    'Hipolipemiante': [
        'alirocumab', 'Acido fenofibrico', 'Atorvastatina', 'Colestiramina', 'Evolocumab',
        'Ezetimibe', 'Fenofibrato', 'Lovastatina'
    ],
    'Antidiabético': [
        'Dapagliflozina', 'Dulaglutida', 'Empagliflozina', 'Glibenclamida', 'Glimepirida'
    ],
    'Insulina': [
        'Insulina', 'Glargina', 'Glulisina', 'Insulina detemir', 'Insulina Glargina',
        'Insulina lispro', 'Degludec', 'Lantus'
    ]
}
def contar_medicamentos(datos, grupo, medicamentos_lista):
    conteo_medicamentos = []
    medicamentos_filtrados = [med for med in medicamentos_lista if med in datos.columns]
    for med in medicamentos_filtrados:
        conteo = list(datos[med]).count('si')
        conteo_medicamentos.append({'Grupo': grupo, 'Medicamento': med, 'Conteo': conteo})
    return pd.DataFrame(conteo_medicamentos)
def graficar_frecuencias(grupo, df_conteos):
    df_conteos = df_conteos.sort_values(by='Conteo', ascending=False)  # Ordenar por frecuencia descendente
    fig = px.bar(df_conteos, x='Medicamento', y='Conteo', title=f'Frecuencia de Medicamentos - {grupo}', text='Conteo')
    fig.update_traces(textposition='outside')  # Mostrar conteo en la barra
    fig.update_layout(yaxis_title='Conteo', xaxis_title='Medicamento')
    fig.show()
for grupo, medicamentos_lista in medicamentos.items():
    conteos_df = contar_medicamentos(datos.datos, grupo, medicamentos_lista)
    graficar_frecuencias(grupo, conteos_df)